<?php
App::uses('AppModel', 'Model');
App::uses('Utils', 'Lib');
/**
 * Pessoa Model
 *
 * @property Municipio $Municipio
 */
class Pessoa extends AppModel {

  // TODO: criar regra para validar sexo (M ou F).
  // TODO: Violação de chave primária e índice único (e-mail) deve ser informado ao usuário, município não cadastrado.

/**
 * Regras de validação
 *
 * @var array
 */
  public $validate = array(
    'nome' => array(
      'obrigatorio' => array(
        'rule' => array('notempty'),
        'message' => 'Obrigatório'
      ),
      'min_caracteres' => array(
        'rule' => array('minLength', 3),
        'message' => 'O nome deve conter no mínimo 3 caracteres'
      ),
      'caracteres_validos' => array(
        'rule' => array('caracteresValidos', '/^\D{3,}$/i'),
        'message' => 'Caracteres inválidos. Somente letras e espaços são permitidos.'
      ),
    ),
    'sexo' => array(
      'obrigatorio' => array(
        'rule' => array('notempty'),
        'message' => 'Obrigatório'
      ),
      'lista' => array(
        'rule' => array('inList', array('F', 'M')),
        'message' => 'Sexo inválido'
      )
    ),
    'data_nascimento' => array(
      'obrigatorio' => array(
        'rule' => array('notEmpty'),
        'message' => 'Obrigatório'
      ),
      'date' => array(
        'rule' => array('date'),
        'message' => 'Data inválida'
      )
    ),
    'email' => array(
      'obrigatorio' => array(
         'rule' => array('notEmpty'),
        'message' => 'Obrigatório'
      ),
      'email' => array(
        'rule' => array('email', true), // true no segundo parâmetro, para verificar o host do endereço de e-mail.
        'message' => 'E-mail inválido'
      )
    ),
    'senha' => array(
      'obrigatorio' => array(
        'rule' => array('notempty'),
        'message' => 'Obrigatório'
      ),
      'min_caracteres' => array(
        'rule' => array('minLength', 6),
        'message' => 'A senha deve conter no mínimo 6 caracteres'
      ),
      'confirmar_senha' => array(
        'rule' => array('confirmarSenha'),
        'message' => 'As senhas não conferem'
      )
    ),
    'municipio_id' => array(
      'obrigatorio' => array(
        'rule' => array('notempty'),
        'message' => 'Obrigatório'
      ),
      'numeric' => array(
        'rule' => array('numeric'),
        'message' => 'Município inválido'
      ),
    ),
    'telefone_residencial' => array(
      'telefone' => array(
        'rule' => array('phone', null, 'us'),
        'message' => 'Número de telefone inválido',
        'allowEmpty' => true
      )
    ),
    'telefone_celular' => array(
      'telefone' => array(
        'rule' => array('phone', null, 'us'),
        'message' => 'Número de telefone inválido',
        'allowEmpty' => true
      )
    ),
    'fotografia' => array(
      'erros_de_upload' => array(
        'rule' => array('errosDeUpload')
        // 'message' será setado pela função de validação em caso de erro.
      ),
      'image' => array(
        'rule' => array('extension', array('jpeg', 'jpg', 'png')),
        'message' => 'Arquivo inválido'
      ),
      'tamanho_do_arquivo' => array(
        'rule' => array('tamanhoDoArquivo', '300k'),
        'message' => 'Arquivo com tamanho superior a 300Kbits não permitido'
      ),
      'arquivo_valido' => array(
        'rule' => array('arquivoValido'),
        'message' => 'Arquivo inválido'
      ),
      'dimensoes_em_pixels' => array(
        'rule' => array('dimensoesEmPixels', 300, 400, false),
        'message' => 'A resolução não pode ultrapassar 300 pixels de largura por 400 pixels de altura'
      )
    )
  );

  // As Associações abaixo foram criados com todas as chaves possíveis, aqueles que não são necessários pode ser removido.

/**
 * Associações "pertence à".
 *
 * @var array
 */
  public $belongsTo = array(
    'Municipio' => array(
      'className' => 'Municipio',
      'foreignKey' => 'municipio_id',
      'conditions' => '',
      'fields' => '',
      'order' => ''
    )
  );

  // CakePHP Callbacks ----------------------------------------------------------------------------------------------------------------------------{{{
  public function beforeSave() {
    if (isset($this->data[$this->alias]['nome'])) {
      $this->data[$this->alias]['nome'] = Utils::formatarNomeProprio($this->data[$this->alias]['nome']);
    }
    //
    if (isset($this->data[$this->alias]['sexo'])) {
      $this->data[$this->alias]['sexo'] = strtoupper($this->data[$this->alias]['sexo']);
    }
    //
    if (isset($this->data[$this->alias]['senha'])) {
      $this->data[$this->alias]['senha'] = AuthComponent::password($this->data[$this->alias]['senha']);
    }
    //
    if (!isset($this->data[$this->alias]['fumante'])) {
      $this->data[$this->alias]['fumante'] = 'f';
    }
    //
    if (isset($this->data[$this->alias]['fotografia'])) {
      // TODO: o nome do arquivo deve ser o id da pessoa.
      // SELECT CASE WHEN is_called THEN last_value + increment_by ELSE start_value END AS proximo_id FROM pessoas_id_seq;
      $destino = Configure::read("DiretorioDeFotografiasDasPessoas") . DS . $this->data[$this->alias]['fotografia']['name'];
      //
      if (!@move_uploaded_file($this->data[$this->alias]['fotografia']['tmp_name'], $destino)) {
        // TODO: Esse tipo de erro deve ser gravado no log.
        $this->validationErrors['fotografia'] = array('Erro no upload');
        return false;
      }
      //
      chmod($destino, 0644);
      $this->data[$this->alias]['fotografia'] = $this->data[$this->alias]['fotografia']['name'];
    }
    return true;
  }

  public function beforeValidate() {
    // Formata a data de nascimento no formato americano YYYY-MM-DD
    $this->data[$this->alias]['data_nascimento'] = Utils::converterDataDMYParaSQL($this->data[$this->alias]['data_nascimento']);
    // Removerespaços extras no início e no fim
    $this->data[$this->alias]['nome'] = trim($this->data[$this->alias]['nome']);
    // Remover máscaras
    $this->data[$this->alias]['telefone_residencial'] = mb_ereg_replace("[^0-9]", "", $this->data[$this->alias]['telefone_residencial']);
    $this->data[$this->alias]['telefone_celular'] = mb_ereg_replace("[^0-9]", "", $this->data[$this->alias]['telefone_celular']);
  }
  // ----------------------------------------------------------------------------------------------------------------------------------------------}}}

  // Métodos customizados de validação ------------------------------------------------------------------------------------------------------------{{{
  public function caracteresValidos($dados, $padrao) {
    if (!preg_match($padrao, $dados['nome'])) {
      return false;
    }
    return true;
  }

  public function confirmarSenha($dados) {
    if ($this->data[$this->alias]['senha'] === $this->data[$this->alias]['confirmar_senha']) {
      return true;
    }
    return true;
  }

  public function errosDeUpload($dados) {
    $mensagensDeErro = array(
      UPLOAD_ERR_INI_SIZE   => "O arquivo enviado excede a diretiva upload_max_filesize em php.ini.",
      UPLOAD_ERR_FORM_SIZE  => "O arquivo enviado excede o tamanho em MAX_FILE_SIZE que foi especificado no formulário HTML.",
      UPLOAD_ERR_PARTIAL    => "O arquivo foi apenas parcialmente carregado.",
      UPLOAD_ERR_NO_TMP_DIR => "Faltando uma pasta temporária.",
      UPLOAD_ERR_CANT_WRITE => "Falha ao gravar arquivo em disco.",
      UPLOAD_ERR_EXTENSION  => "Arquivo de upload parou por extensão."
    );
    //
    if ($dados['fotografia']['error'] !== UPLOAD_ERR_OK and $dados['fotografia']['error'] !== UPLOAD_ERR_NO_FILE) {
      $this->validationErrors['fotografia'] = array($mensagensDeErro[$dados['fotografia']['error']]);
      return false;
    }
    return true;
  }

  public function tamanhoDoArquivo($dados, $tamanho) {
    $tamanho = Utils::obterTamanhoEmBytes($tamanho);
    if ($dados['fotografia']['size'] > $tamanho) {
      return false;
    }
    return true;
  }

  public function arquivoValido($dados) {
    $dimensoes = getimagesize($dados['fotografia']['tmp_name']);
    //
    switch ($dimensoes[2]) {
      case IMAGETYPE_JPEG:
        $imagem = @imagecreatefromjpeg($dados['fotografia']['tmp_name']);
        break;
      case IMAGETYPE_PNG:
        $imagem = @imagecreatefrompng($dados['fotografia']['tmp_name']);
      break;
      default:
        $imagem = false;
    }
    //
    if (!$imagem) {
      return false;
    }
    return true;
  }

  public function dimensoesEmPixels($dados, $largura, $altura, $valoresExatos = false) {
    $dimensoes = getimagesize($dados['fotografia']['tmp_name']);
    //
    if (!$dimensoes[0] or !$dimensoes[1]) {
      return false;
    } elseif ($valoresExatos === false or $valoresExatos === null) {
      if ($dimensoes[0] > $largura or $dimensoes[1] > $altura) {
        return false;
      }
    } elseif ($dimensoes[0] !== $largura or $dimensoes[1] !== $altura) {
      return false;
    }
    return true;
  }
  // ----------------------------------------------------------------------------------------------------------------------------------------------}}}

}
